package cn.daniellee.plugin.ib.listener;

import cn.daniellee.plugin.ib.InfiniteBlock;
import cn.daniellee.plugin.ib.core.BlockCore;
import cn.daniellee.plugin.ib.menu.BlockMenu;
import cn.daniellee.plugin.ib.menu.EditMenu;
import cn.daniellee.plugin.ib.menu.AdminMenu;
import cn.daniellee.plugin.ib.model.PlayerData;
import cn.daniellee.plugin.ib.model.Edit;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.*;
import org.bukkit.inventory.Inventory;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MenuListener implements Listener {

	/**
	 * 处理排队菜单和确认菜单的点击事件
	 * @param e 事件
	 */
	@EventHandler
	public void onInventoryClick(InventoryClickEvent e) {
		Inventory menu = e.getInventory();
		if (menu != null && menu.getHolder() != null) {
			if (menu.getHolder() instanceof BlockMenu.BuildingMenuHolder) {
				e.setCancelled(true);
				Player player = (Player) e.getWhoClicked();
				if (e.getCurrentItem() == null || e.getCurrentItem().getItemMeta() == null) return;
				String itemName = e.getCurrentItem().getItemMeta().getDisplayName();
				if (e.getRawSlot() == 45 || e.getRawSlot() == 53) {
					Inventory playerMenu = BlockMenu.generate(player, Integer.valueOf(itemName.substring(itemName.indexOf("[") + 1, itemName.indexOf("]"))));
					player.openInventory(playerMenu);
				} else {
					String id = itemName.substring(itemName.lastIndexOf("(") + 1, itemName.lastIndexOf(")"));
					PlayerData playerData = BlockCore.getBuildingById(id);
					if (playerData != null) {
						if (e.getClick().isShiftClick()) {
							if (e.getClick().isLeftClick()) {
								if (player.getName().equals(playerData.getPlayer()) || player.hasPermission("playerData.modify.force")) {
									BlockCore.editingBuilding.put(player.getName(), id);
									player.openInventory(EditMenu.generate());
								}
							}
						} else {
							if (e.getClick().isLeftClick()) {
								player.closeInventory();
								BlockCore.teleportToBuilding(player, playerData);
							} else if (e.getClick().isRightClick()) {
								List<String> liker = playerData.getLiker() != null ? new ArrayList<>(Arrays.asList(playerData.getLiker().split(","))) : new ArrayList<>();
								if (liker.contains(player.getName())) {
									player.sendMessage((InfiniteBlock.getInstance().getPrefix() + InfiniteBlock.getInstance().getConfig().getString("message.already-like", "&eYou have already praised this playerData.")).replace("&", "§"));
								} else {
									liker.add(player.getName());

									InfiniteBlock.getInstance().getStorage().updateBuilding(id, "likes", Integer.toString(playerData.getLikes() + 1));
									InfiniteBlock.getInstance().getStorage().updateBuilding(id, "liker", StringUtils.join(liker, ","));
									player.closeInventory();
									if (!InfiniteBlock.getInstance().getConfig().getBoolean("setting.disable-like-boardcast", false)) {
										BlockCore.sendMessageToAll(player, (InfiniteBlock.getInstance().getPrefix() + InfiniteBlock.getInstance().getConfig().getString("message.boardcast.like-success", "&d{player} &ehas successfully liked the &c{owner}&e`s playerData &d{name}&e!").replace("{player}", player.getName()).replace("{owner}", playerData.getPlayer()).replace("{name}", playerData.getName())).replace("&", "§"));
									}
									// 向所有服务器发送消息
									BlockCore.sendRefreshMessage(player);
								}
							}
						}
					}
				}
			} else if (menu.getHolder() instanceof AdminMenu.ReviewMenuHolder) {
				e.setCancelled(true);
				Player player = (Player) e.getWhoClicked();
				if (!player.hasPermission("building.command.review")) return;
				if (e.getCurrentItem() == null || e.getCurrentItem().getItemMeta() == null) return;
				String itemName = e.getCurrentItem().getItemMeta().getDisplayName();
				if (e.getRawSlot() == 45 || e.getRawSlot() == 53) {
					Inventory playerMenu = BlockMenu.generate(player, Integer.valueOf(itemName.substring(itemName.indexOf("[") + 1, itemName.indexOf("]"))));
					player.openInventory(playerMenu);
				} else {
					String id = itemName.substring(itemName.indexOf("(") + 1);
					id = id.substring(0, id.indexOf(")"));
					PlayerData playerData = BlockCore.getBuildingById(id);
					if (playerData != null) {
						if (e.getClick().isShiftClick()) {
							if (e.getClick().isLeftClick()) {
								playerData.setReviewed(true);
								InfiniteBlock.getInstance().getStorage().updateBuilding(id, "reviewed", "true");
								BlockCore.sendMessageToAll(player, (InfiniteBlock.getInstance().getPrefix() + InfiniteBlock.getInstance().getConfig().getString("message.boardcast.review-pass", "&c{owner}&e's playerData &d{name}&e has passed the excellent playerData review, go visit it!").replace("{owner}", playerData.getPlayer()).replace("{name}", playerData.getName())).replace("&", "§"));
								// 重新打开以刷新
								player.openInventory(AdminMenu.generate(1));
								// 向所有服务器发送消息
								BlockCore.sendRefreshMessage(player);
							} else if (e.getClick().isRightClick()) {
								InfiniteBlock.getInstance().getStorage().deleteBuilding(id);
								player.sendMessage((InfiniteBlock.getInstance().getPrefix() + InfiniteBlock.getInstance().getConfig().getString("message.review-denied", "&eSuccessfully rejected the review of this playerData.")).replace("&", "§"));
								// 重新打开以刷新
								player.openInventory(AdminMenu.generate(1));
								// 向所有服务器发送消息
								BlockCore.sendRefreshMessage(player);
							}
						} else {
							if (e.getClick().isLeftClick()) {
								player.closeInventory();
								BlockCore.teleportToBuilding(player, playerData);
							}
						}
					}
				}
			} else if (menu.getHolder() instanceof EditMenu.EditMenuHolder) {
				e.setCancelled(true);
				// 防止取出物品
				if (e.isShiftClick()) return;
				Player player = (Player) e.getWhoClicked();
				String id = BlockCore.editingBuilding.get(player.getName());
				if (id != null) {
					PlayerData playerData = BlockCore.getBuildingById(id);
					if (playerData != null) {
						if (player.getName().equals(playerData.getPlayer()) || player.hasPermission("playerData.modify.force")) {
							if (e.getRawSlot() == 0) {
								BlockCore.editOperation.put(player.getName(), new Edit(id, "Name"));
								player.sendMessage((InfiniteBlock.getInstance().getPrefix() + InfiniteBlock.getInstance().getConfig().getString("message.typein-chat", "&ePlease enter the new name into the chat box or enter &ccancel &eto cancel.")).replace("&", "§"));
								player.closeInventory();
							} else if (e.getRawSlot() == 1) {
								Edit edit = new Edit(id, "Intro");
								List<String> introduction = new ArrayList<>();
								if (playerData.getIntroduction() != null && !"".equals(playerData.getIntroduction())) {
									introduction.addAll(new Gson().fromJson(playerData.getIntroduction(), new TypeToken<List<String>>(){}.getType()));
								}
								edit.setIntroduction(introduction);
								BlockCore.editOperation.put(player.getName(), edit);
								player.sendMessage((InfiniteBlock.getInstance().getPrefix() + InfiniteBlock.getInstance().getConfig().getString("message.intro-mode", "&eEnter the introduction edit mode, send &badd [content] &eto add a line, send &bset [line] [content] &eto modify a line, send &bdel [line] &eto delete a line, send &bok &eto complete, send &bcancel &eto cancel, the current introduction is:")).replace("&", "§"));
								for (int i = 0; i < introduction.size(); i++) player.sendMessage(("&e" + (i + 1) + ". &r" + introduction.get(i)).replace("&", "§"));
								player.closeInventory();
							} else if (e.getRawSlot() == 2) {
								Edit edit = BlockCore.editOperation.get(player.getName());
								if (edit == null || !"Location".equals(edit.getOperation())) {
									edit = new Edit(id, "Location");
									BlockCore.editOperation.put(player.getName(), edit);
									player.sendMessage((InfiniteBlock.getInstance().getPrefix() + InfiniteBlock.getInstance().getConfig().getString("message.reclick-setloc", "&eClick again to confirm the update location.")).replace("&", "§"));
								} else {
									BlockCore.editOperation.remove(player.getName());
									InfiniteBlock.getInstance().getStorage().updateBuilding(id, "server", BlockCore.serverName);
									Location location = player.getLocation();
									InfiniteBlock.getInstance().getStorage().updateBuilding(id, "location", location.getWorld().getName() + "," + location.getBlockX() + "," + location.getBlockY() + "," + location.getBlockZ() + "," + (int) location.getYaw() + "," + (int) location.getPitch());
									InfiniteBlock.getInstance().getStorage().updateBuilding(id, "reviewed", "false");
									player.sendMessage((InfiniteBlock.getInstance().getPrefix() + InfiniteBlock.getInstance().getConfig().getString("message.setloc-success", "&eSuccessfully updated playerData location, management will review for you as soon as possible.")).replace("&", "§"));
									player.closeInventory();
									BlockCore.sendRefreshMessage(player);
								}
							} else if (e.getRawSlot() == 3) {
								InfiniteBlock.getInstance().getStorage().updateBuilding(id, "icon_material", player.getItemInHand().getType() != Material.AIR ? player.getItemInHand().getType().toString() : null);
								InfiniteBlock.getInstance().getStorage().updateBuilding(id, "icon_durability", player.getItemInHand().getType() != Material.AIR ? String.valueOf(player.getItemInHand().getDurability()) : "0");
								player.sendMessage((InfiniteBlock.getInstance().getPrefix() + InfiniteBlock.getInstance().getConfig().getString("message.seticon-success", "&eSuccessfully updated playerData icon.")).replace("&", "§"));
								player.closeInventory();
								BlockCore.sendRefreshMessage(player);
							} else if (e.getRawSlot() == 4) {
								Edit edit = BlockCore.editOperation.get(player.getName());
								if (edit == null || !"Delete".equals(edit.getOperation())) {
									edit = new Edit(id, "Delete");
									BlockCore.editOperation.put(player.getName(), edit);
									player.sendMessage((InfiniteBlock.getInstance().getPrefix() + InfiniteBlock.getInstance().getConfig().getString("message.reclick-delete", "&eClick again to confirm the deletion of the playerData.")).replace("&", "§"));
								} else {
									BlockCore.editOperation.remove(player.getName());
									InfiniteBlock.getInstance().getStorage().deleteBuilding(id);
									player.sendMessage((InfiniteBlock.getInstance().getPrefix() + InfiniteBlock.getInstance().getConfig().getString("message.delete-success", "&eSuccessfully deleted playerData.")).replace("&", "§"));
									player.closeInventory();
									BlockCore.sendRefreshMessage(player);
								}
							}
						}
					}
				}
			}
		}
	}

}
